gccfandomcom_ja-20200214-history
Invert truthvalue
概要 *Gcc-4.1.0/gcc/fold-const.cにて定義 引数 *tree arg 実装 2959 /* Return a simplified tree node for the truth-negation of ARG. This 2960 never alters ARG itself. We assume that ARG is an operation that 2961 returns a truth value (0 or 1). 2962 2963 FIXME: one would think we would fold the result, but it causes 2964 problems with the dominator optimizer. */ 2965 tree 2966 invert_truthvalue (tree arg) 2967 { 2968 tree type = TREE_TYPE (arg); 2969 enum tree_code code = TREE_CODE (arg); 2970 2971 if (code ERROR_MARK) 2972 return arg; 2973 2974 /* If this is a comparison, we can simply invert it, except for 2975 floating-point non-equality comparisons, in which case we just 2976 enclose a TRUTH_NOT_EXPR around what we have. */ 2977 2978 if (TREE_CODE_CLASS (code) tcc_comparison) 2979 { 2980 tree op_type = TREE_TYPE (TREE_OPERAND (arg, 0)); 2981 if (FLOAT_TYPE_P (op_type) 2982 && flag_trapping_math 2983 && code != ORDERED_EXPR && code != UNORDERED_EXPR 2984 && code != NE_EXPR && code != EQ_EXPR) 2985 return build1 (TRUTH_NOT_EXPR, type, arg); 2986 else 2987 { 2988 code = invert_tree_comparison (code, 2989 HONOR_NANS (TYPE_MODE (op_type))); 2990 if (code ERROR_MARK) 2991 return build1 (TRUTH_NOT_EXPR, type, arg); 2992 else 2993 return build2 (code, type, 2994 TREE_OPERAND (arg, 0), TREE_OPERAND (arg, 1)); 2995 } 2996 } 2997 2998 switch (code) 2999 { 3000 case INTEGER_CST: 3001 return constant_boolean_node (integer_zerop (arg), type); 3002 3003 case TRUTH_AND_EXPR: 3004 return build2 (TRUTH_OR_EXPR, type, 3005 invert_truthvalue (TREE_OPERAND (arg, 0)), 3006 invert_truthvalue (TREE_OPERAND (arg, 1))); 3007 3008 case TRUTH_OR_EXPR: 3009 return build2 (TRUTH_AND_EXPR, type, 3010 invert_truthvalue (TREE_OPERAND (arg, 0)), 3011 invert_truthvalue (TREE_OPERAND (arg, 1))); 3012 3013 case TRUTH_XOR_EXPR: 3014 /* Here we can invert either operand. We invert the first operand 3015 unless the second operand is a TRUTH_NOT_EXPR in which case our 3016 result is the XOR of the first operand with the inside of the 3017 negation of the second operand. */ 3018 3019 if (TREE_CODE (TREE_OPERAND (arg, 1)) TRUTH_NOT_EXPR) 3020 return build2 (TRUTH_XOR_EXPR, type, TREE_OPERAND (arg, 0), 3021 TREE_OPERAND (TREE_OPERAND (arg, 1), 0)); 3022 else 3023 return build2 (TRUTH_XOR_EXPR, type, 3024 invert_truthvalue (TREE_OPERAND (arg, 0)), 3025 TREE_OPERAND (arg, 1)); 3026 3027 case TRUTH_ANDIF_EXPR: 3028 return build2 (TRUTH_ORIF_EXPR, type, 3029 invert_truthvalue (TREE_OPERAND (arg, 0)), 3030 invert_truthvalue (TREE_OPERAND (arg, 1))); 3031 3032 case TRUTH_ORIF_EXPR: 3033 return build2 (TRUTH_ANDIF_EXPR, type, 3034 invert_truthvalue (TREE_OPERAND (arg, 0)), 3035 invert_truthvalue (TREE_OPERAND (arg, 1))); 3036 3037 case TRUTH_NOT_EXPR: 3038 return TREE_OPERAND (arg, 0); 3039 3040 case COND_EXPR: 3041 { 3042 tree arg1 = TREE_OPERAND (arg, 1); 3043 tree arg2 = TREE_OPERAND (arg, 2); 3044 /* A COND_EXPR may have a throw as one operand, which 3045 then has void type. Just leave void operands 3046 as they are. */ 3047 return build3 (COND_EXPR, type, TREE_OPERAND (arg, 0), 3048 VOID_TYPE_P (TREE_TYPE (arg1)) 3049 ? arg1 : invert_truthvalue (arg1), 3050 VOID_TYPE_P (TREE_TYPE (arg2)) 3051 ? arg2 : invert_truthvalue (arg2)); 3052 } 3053 3054 case COMPOUND_EXPR: 3055 return build2 (COMPOUND_EXPR, type, TREE_OPERAND (arg, 0), 3056 invert_truthvalue (TREE_OPERAND (arg, 1))); 3057 3058 case NON_LVALUE_EXPR: 3059 return invert_truthvalue (TREE_OPERAND (arg, 0)); 3060 3061 case NOP_EXPR: 3062 if (TREE_CODE (TREE_TYPE (arg)) BOOLEAN_TYPE) 3063 break; 3064 3065 case CONVERT_EXPR: 3066 case FLOAT_EXPR: 3067 return build1 (TREE_CODE (arg), type, 3068 invert_truthvalue (TREE_OPERAND (arg, 0))); 3069 3070 case BIT_AND_EXPR: 3071 if (!integer_onep (TREE_OPERAND (arg, 1))) 3072 break; 3073 return build2 (EQ_EXPR, type, arg, 3074 fold_convert (type, integer_zero_node)); 3075 3076 case SAVE_EXPR: 3077 return build1 (TRUTH_NOT_EXPR, type, arg); 3078 3079 case CLEANUP_POINT_EXPR: 3080 return build1 (CLEANUP_POINT_EXPR, type, 3081 invert_truthvalue (TREE_OPERAND (arg, 0))); 3082 3083 default: 3084 break; 3085 } 3086 gcc_assert (TREE_CODE (TREE_TYPE (arg)) BOOLEAN_TYPE); 3087 return build1 (TRUTH_NOT_EXPR, type, arg); 3088 }